{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true,
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!mkdir -p ~/.keras/datasets/\n",
    "!wget -O ~/.keras/datasets/cifar-10-batches-py.tar.gz http://dl4img-1251985129.cosbj.myqcloud.com/cifar-10-batches-py.tar.gz\n",
    "!tar -zxvf ~/.keras/datasets/cifar-10-batches-py.tar.gz -C ~/.keras/datasets/"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from __future__ import print_function\n",
    "import numpy as np\n",
    "from keras.callbacks import TensorBoard\n",
    "from keras.models import Sequential\n",
    "from keras.optimizers import Adam\n",
    "from keras.layers import Dense, Dropout, Activation, Flatten\n",
    "from keras.layers import Conv2D, MaxPool2D\n",
    "from keras.utils import np_utils\n",
    "from keras import backend as K\n",
    "from keras.callbacks import ModelCheckpoint\n",
    "from keras.datasets import cifar10\n",
    "\n",
    "from keras.backend.tensorflow_backend import set_session\n",
    "import tensorflow as tf\n",
    "config = tf.ConfigProto()\n",
    "config.gpu_options.allow_growth=True\n",
    "set_session(tf.Session(config=config))\n",
    "\n",
    "\n",
    "np.random.seed(42)\n",
    "print(\"Initialized!\")\n",
    "\n",
    "# 定义变量\n",
    "batch_size = 32\n",
    "nb_classes = 10\n",
    "nb_epoch = 50\n",
    "img_rows, img_cols = 32, 32\n",
    "nb_filters = [32, 32, 64, 64]\n",
    "pool_size = (2, 2)\n",
    "kernel_size = (3, 3)\n",
    "\n",
    "#\n",
    "(X_train, y_train), (X_test, y_test) = cifar10.load_data()\n",
    "X_train = X_train.astype(\"float32\") / 255\n",
    "X_test  = X_test.astype(\"float32\") / 255\n",
    "\n",
    "y_train = y_train\n",
    "y_test = y_test\n",
    "\n",
    "\n",
    "input_shape = (img_rows, img_cols, 3)\n",
    "Y_train = np_utils.to_categorical(y_train, nb_classes)\n",
    "Y_test = np_utils.to_categorical(y_test, nb_classes)\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "上游部分， 基于生成器的批量生成输入模块："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "\n",
    "datagen = ImageDataGenerator(\n",
    "            featurewise_center=False,\n",
    "            samplewise_center=False,\n",
    "            featurewise_std_normalization=False,\n",
    "            samplewise_std_normalization=False,\n",
    "            zca_whitening=False,\n",
    "            rotation_range=0,\n",
    "            width_shift_range=0.1,\n",
    "            height_shift_range=0.1,\n",
    "            horizontal_flip=True,\n",
    "            vertical_flip=False)\n",
    "\n",
    "datagen.fit(X_train)\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "核心部分，用各种零件搭建深度神经网络："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "model = Sequential()\n",
    "model.add(Conv2D(nb_filters[0], kernel_size, padding='same',input_shape=X_train.shape[1:]))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Conv2D(nb_filters[1], kernel_size))\n",
    "model.add(Activation('relu'))\n",
    "model.add(MaxPool2D(pool_size=pool_size))\n",
    "model.add(Dropout(0.25))\n",
    "\n",
    "model.add(Conv2D(nb_filters[2], kernel_size, padding='same'))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Conv2D(nb_filters[3], kernel_size))\n",
    "model.add(Activation('relu'))\n",
    "model.add(MaxPool2D(pool_size=pool_size))\n",
    "model.add(Dropout(0.25))\n",
    "\n",
    "model.add(Flatten())\n",
    "model.add(Dense(512))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Dropout(0.5))\n",
    "model.add(Dense(nb_classes))\n",
    "model.add(Activation('softmax'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "下游部分，使用凸优化模块："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "adam = Adam(lr=0.0001)\n",
    "model.compile(loss='categorical_crossentropy',\n",
    "                   optimizer=adam,\n",
    "                   metrics=['accuracy'])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "best_model = ModelCheckpoint(\"cifar10_best.h5\", monitor='val_loss', verbose=0, save_best_only=True)\n",
    "tb = TensorBoard(log_dir=\"./logs\")\n",
    "model.fit_generator(datagen.flow(X_train, Y_train, batch_size=batch_size),\n",
    "                        steps_per_epoch=X_train.shape[0] // batch_size,\n",
    "                        epochs=nb_epoch, verbose=1,\n",
    "                        validation_data=(X_test, Y_test), callbacks=[best_model,tb])\n",
    "\n",
    "\n",
    "# 模型评分\n",
    "score = model.evaluate(X_test, Y_test, verbose=0)\n",
    "# 输出结果\n",
    "print('Test score:', score[0])\n",
    "print(\"Accuracy: %.2f%%\" % (score[1]*100))                   \n",
    "print(\"Compiled!\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import pydot\n",
    "import graphviz"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "from keras.utils.vis_utils import model_to_dot\n",
    "from IPython.display import SVG\n",
    "SVG(model_to_dot(model=model, show_layer_names=True, show_shapes=True).create(prog='dot', format='svg'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
